package com.datang.litejvm.engin;


import com.datang.litejvm.clz.Field;
import com.datang.litejvm.clz.Method;
import com.datang.litejvm.constant.ConstantFieldRefInfo;
import com.datang.litejvm.constant.ConstantMethodRefInfo;
import com.datang.litejvm.loader.ClassLoader;
import com.datang.litejvm.clz.Class;
import java.util.HashMap;
import java.util.Map;

/**
 * @author: 顶风少年
 * @Description: 方法区
 * @date: 10:49 2022/6/16
 **/
public class MethodArea {
	
	public static final MethodArea instance = new MethodArea();
	
	/**
	 * 注意：我们做了极大的简化， ClassLoader 只有一个， 实际JVM中的ClassLoader,是一个双亲委托的模型
	 */
	
	private ClassLoader classLoader = null;

	/**
	 * @author: 顶风少年
	 * @Description: 存放所有的Class
	 * @date: 10:39 2022/6/16
	 **/
	Map<String, Class> map = new HashMap<String, Class>();
	
	private MethodArea(){		
	}

	/**
	 * @author: 顶风少年
	 * @Description: 单例,获取常量池
	 * @date: 10:39 2022/6/16
	 **/
	public static MethodArea getInstance(){
		return instance;
	}
	
	public void setClassFileLoader(ClassLoader clzLoader){
		this.classLoader = clzLoader;
	}

	/**
	 * @author: 顶风少年
	 * @Description: 获取main方法
	 * @date: 10:39 2022/6/16
	 **/
	public Method getMainMethod(String className){
		Class clz = this.findClass(className);
		return clz.getMainMethod();
	}

	/**
	 * @author: 顶风少年
	 * @Description: 从指定class中 根据名称获取方法
	 * @date: 22:23 2022/6/16
	 **/
	public Method getMethod(ConstantMethodRefInfo constantMethodRefInfo){
		Class aClass = findClass(constantMethodRefInfo.getClassName());
		Method method = aClass.getMethod(constantMethodRefInfo.getMethodName(), constantMethodRefInfo.getParamAndResult());
		return method;
	}

	/**
	 * @author: 顶风少年
	 * @Description: 创建Class
	 * @date: 10:38 2022/6/16
	 **/
	public Class findClass(String className){
		if(map.get(className) != null){
			return map.get(className);
		}
		// 看来该class 文件还没有load过
		Class aClass = this.classLoader.loadClass(className);
		map.put(className, aClass);
		return aClass;
	}
}
